将更新推送到已修剪的Mercurial分支

时间:2009-05-21 00:29:59

标签: git mercurial merge branch dvcs

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

我希望对主服务器进行进一步的更新,这些更新不会影响可以向从服务器推送的敏感文件,并且可以由主服务器对从属服务器进行更新。现在这不会发生,因为它们被认为是“无关的”存储库

如果Git可以实现这一点,但Mercurial没有,迁移是可能的,尽管由于某些开发发生在Windows机器上,这将是一个麻烦。奴隶还没有看到外面使用的活跃,因此有可能将其核对并在必要时以另一种方式重新创建它。如果绝对必要的话,甚至可以完全转储主服务器并从服务器重新克隆,然后让所有敏感部分完全无版本化,但我更不希望不必这样做,因为其中一些文件 正在改变,我想跟踪这些变化。

有没有人有什么好主意?

更新:我一直在讨论关于Git的文档 - 可以使用Git暂存区轻松实现“推送除了这些之外的所有文件”命令吗?

更新2:这对我没有帮助,但它可能对有类似问题的人有所帮助:您可以反复使用hg convert --filemap,它只会跟踪对主人的更新,但如果目标存储库是通过文件系统编写的,则此有效,并且无法通过网络工作。当然,它也没有相反的方向。

3 个答案:

答案 0 :(得分:1)

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

让我试着解释一下内部存储库的含义。我们有两个正常的,独立的存储库:'slave'和'master'。您将所有公共文件放在“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”并在那里提交,就像正常一样。

你可以像普通的那样在'奴隶'克隆和'主'克隆之间拉/推,因为它们是......,只是普通的克隆。你说项目不是秘密/公共文件不应该被视为嵌套项目,但我建议你进行这种区分,以便将它们分成两个目录。

请注意,我假设你可以将所有公共文件限制在秘密文件的子目录中。如果您将“奴隶克隆”重命名为“公共”或“公告”或类似名称,我认为这听起来并不太遥远: - )

否则,您可以使用一堆符号链接执行某些操作,以便通过将文件符号链接到单个目录来“加入”存储库。

答案 1 :(得分:1)

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

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

如果更改混合存储库中的公共文件,则必须首先确保已更新到来自“从属”存储库的变更集。否则你将无法提交并将新的变更设置为“slave”。所以如果你在[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页面底部找到。我相信subchapo扩展正在为Mercurial 1.3工作,但我们必须看到(发布日期是7月1日)。

答案 2 :(得分:1)

好吧,看起来真正的答案是,“Mercurial不能做你想要的”(这是在存储库和分支机构之间进行同步,这是该存储库的一个严格子集)没有使用一些可怕的不方便系统就像补丁队列一样。 Git可能有,但由于它的Windows端口还没有准备好用于生产,我看起来并不那么难。

然而,事实证明可以重新组织项目,以便可以将公共和私人部分拆分成单独的存储库,只有相对较小的历史记录。 (实际上,它在我们使用时分为三种方式 - 公共部分,我们放在子目录local/中的公共部分特定于机器的部分(因此可以将其克隆到大部分机器中)几乎相同的规格,而不必维护和合并几个奇怪的分支上的额外分支),以及我们放在子目录private/中的私有部分。)诀窍结果是没有尝试将清理的奴隶放入主人,但要从主服务器中拆分私有/本地部分,并将它们作为(伪)子存储库放在主计算机上的从属存储库中。

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

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

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