1

我有两个相关的存储库,一个主存储库,其中包含许多不得泄露的敏感文件,以及一个“公共”版本,使用 hg convert 和 --filemap 创建以排除敏感文件和目录。

我希望对不影响敏感文件的主机进行进一步更新,使其可推送到从机,并更新从机以供主机拉取。现在这不会发生,因为它们被认为是“不相关”的存储库

如果这在 Git 上可行,但在 Mercurial 上不行,那么迁移是可能的,尽管这会很麻烦,因为某些开发发生在 Windows 机器上。从站尚未看到活跃的外部使用,因此可以在必要时对其进行核攻击并以另一种方式重新创建它。如果绝对有必要,甚至可以完全转储主服务器并从从服务器重新克隆,然后将所有敏感部分完全不版本化,但我非常希望不必这样做,因为其中一些文件正在发生变化,我想跟踪这些变化。

有没有人有什么好主意?

更新:我一直在查看 Git 上的文档——可以使用 Git 暂存区轻松实现“推送除这些文件之外的所有文件”命令吗?

更新 2:这对我没有帮助,但它可能对有类似问题的人有所帮助:您可以hg convert --filemap重复使用,它只会跟踪对 master 的更新,但这适用于目标存储库是通过文件系统编写的,并且赢了不要在电线上工作。当然,它也无助于相反的方向。

4

3 回答 3

1

我想我需要比评论框给我更多的空间... :-)

让我试着解释一下我所说的内部存储库是什么意思。我们有两个正常的、独立的存储库:“slave”和“master”。您将所有公共文件放在“从”中,并将秘密文件放在“主”中:

master/
  secret-file.txt
  another-secret.txt
  more-secrets.jpeg

slave-clone/
  public.png
  more-public.txt

然后通过制作新的克隆来组合它们:

% hg clone master master-clone
% cd master-clone
% hg clone ../slave slave-clone

您现在在“master”的克隆中拥有一个“slave”的克隆:

master-clone/
  secret-file.txt
  another-secret.txt
  slave-clone/
    public.png
    more-public.txt
  more-secrets.jpeg

在此存储库中,您将看到所有 Mercurial 命令都忽略了“slave-clone”,除非您将目录更改为它。所以你可以做

% echo 'evil plans' > plans.txt
% hg add plans.txt
% hg commit -m 'Secret stuff'

因此,您将在外部存储库上进行提交。要编辑一些公开的东西,你输入“slave-clone”并在那里提交,就像平常一样。

您可以像往常一样在“从属”克隆和“主”克隆之间拉/推,因为它们是……嗯……只是普通克隆。您说项目不是秘密/公共文件不应被视为嵌套项目,但我建议您进行此区分以便将它们分成两个目录。

请注意,我假设您可以将所有公共文件限制在秘密文件的子目录中。如果您将 'slave-clone' 重命名为 'public' 或 'announcements' 或类似名称,我认为这听起来不太牵强 :-)

否则,您可能可以使用一堆符号链接来做一些事情,以便通过将文件符号链接到单个目录中来“加入”存储库。

于 2009-05-22T22:59:58.540 回答
1

最简单的解决方案可能是简单地将“奴隶”的克隆放在“主人”中。内部克隆将被外部克隆忽略——因此,当您提交对秘密文件的更改时,您不会冒险将它们与公共文件混合。推拉会像平常一样工作,你必须做两次,一次用于内部,一次用于外部。

或者,您可以强行将“奴隶”拉入“主人”。这将创建一个具有两个根修订版的存储库,但这不是问题。合并后,您将拥有一个混合存储库。然后可以从“从属”中提取新的变更集,而不会发出进一步的警告,因为这两个存储库已经相关。

如果您更改混合存储库中的公共文件,您必须首先确保您已更新到来自“从”存储库的变更集。否则,您将无法提交并将新的变更集设置为“从属”。因此,如果您在 [s3]:

... [s1] --- [s2] ---[s3]
            /
... [p1] --/

并且您想更新公共文件,您需要先更新到 [p1]:

% hg update p1

然后编辑并提交

% hg commit -m 'Public change'
(created new head)

您的历史图表现在将如下所示:

... [s1] --- [s2] ---[s3]
            /
... [p1] --/-[p2]

你会想把 [p2] 推到“奴隶”:

% hg push p2

并将其与 [s3] 合并:

% hg merge

之后你会得到

... [s1] --- [s2] ---[s3] --- [s4]
            /                /
... [p1] --/-[p2] ----------/   

其他解决方案可以在 Mercurial wiki 上的 NestedRepositories 页面底部找到。我相信 Mercurial 1.3 的 subrepo 扩展正在开发中,但我们必须拭目以待(发布日期是 7 月 1 日)。

于 2009-05-21T00:55:34.167 回答
1

好的,看起来真正的答案是,“Mercurial 不能做你想做的事”(即在存储库和作为该存储库的严格子集的分支之间进行同步),而不是使用一些非常不方便的系统,例如补丁队列。Git 可能有,但由于它的 Windows 端口还没有准备好用于生产,所以我并没有那么认真地研究它。

然而,事实证明有可能以这样一种方式重组项目,即可以将公共部分和私有部分分成单独的存储库,而历史损失相对较小。(实际上,当我们使用它时,它被分成了三种方式——公共部分,一个公共但特定于机器的部分,我们放在子目录中local/(因此它可以克隆到具有几乎相同规格的大部分机器上,而无需必须在几个奇怪的分支上维护和合并额外的分支),以及我们放在子目录中的私有部分private/。)结果证明,这个技巧不是试图将一个干净的从属放在主控中,而是将私有/本地部分分开从 master 并将它们作为(伪)sub-repositories 放在 master 机器上的 slave 存储库中。

第 1 阶段是将文件移动到private/local/目录,从主存储库中删除它们,并在替换符号链接在其他机器上出现问题时根据需要将它们添加到 .hgignore。值得庆幸的是,我们必须以这种方式移动的大约 95% 的东西对位置不敏感,其余的我们可以手动管理。这两个目录然后成为他们自己的存储库。

第 2 阶段我们基本上已经完成:hg convert用于--filemap创建存储库的公共版本,其中所有私有数据的痕迹都已被删除。(这实际上需要一些文件映射调整:您不仅必须排除所有当前的私有数据文件名,还必须排除它们过去可能拥有的任何文件名。Mercurial 跟踪文件移动/重命名的能力似乎并不完全强大.)

此时,.hg/master 上的目录被移动到一个备份位置,并且从干净的公共存储库中重新提取。然后,我们运行测试以确保一切正常,并开始将新的基础存储库和选定的local存储库克隆到从机,并对其进行测试,一切似乎都很好,尽管我们不得不调整一些符号链接停止工作的地方(主要是在 Windows 机器上,但奇怪的是,在 Linux 方面,我将不得不深入研究为什么在我有空闲时间时没有遵循符号链接,尽管我们在解决问题时解决了这个问题发现一个特定的文件可以并且确实应该自动重新生成)。

于 2009-05-24T17:43:09.327 回答