3

采取这个回购结构:

Server (main repo)
    ProjectA (subrepo)
    SharedLibrary (subrepo)

Client (main repo)
    ProjectB (subrepo)
    SharedLibrary (subrepo)

SharedLibrary 指向同一个文件夹(这是 Windows),它不是每个主仓库下的单独副本/克隆。

假设每个主仓库都有两个变更集,0 和 1(tip)。我们从 1(tip) 修订版的两个主要回购开始。

采取以下步骤:

  1. 在客户端存储库中,更新到变更集 0。这会将 ProjectB 和 SharedLibrary 更新为较早但匹配的修订版。

  2. ProjectA 现在与 SharedLibrary 不同步。第 1 步将 SharedLibrary 更新为比 ProjectA 所需的版本更旧的版本,该版本仍为 1(tip)。

  3. 在服务器存储库中,我们希望将 SharedLibrary 更新为 ProjectA 的正确修订版,因此我们在服务器主存储库中运行 hg update tip。这不会将 SharedLibrary 更新为正确的版本。它将 SharedLibrary 留在与第一步相同的修订版中。

  4. 返回客户端 repo 并运行 hg update tip。SharedLibrary 现在处于 ProjectA 和 ProjectB 的正确版本。

似乎服务器存储库中的更新并未检查 SharedLibrary 是否处于正确的修订版。这种行为是预期的,还是有更好的方法来做到这一点?

4

1 回答 1

2

您所看到的是当工作副本脏时hg update合并。让我先用一个普通的文件来解释它。想象一下,您有一个包含两个修订版的存储库。我处于修订版 0 并foo已修改:

$ hg diff
diff --git a/foo b/foo
--- a/foo
+++ b/foo
@@ -1,3 +1,3 @@
 first
 second
-third
+third line

你看我改变了第三行。现在,如果我运行hg update 1修改将与修订 1 中的外观合并:foo

$ hg update 1
merging foo
0 files updated, 1 files merged, 0 files removed, 0 files unresolved

修改仍然存在并且foo仍然很脏:

$ hg diff
diff --git a/foo b/foo
--- a/foo
+++ b/foo
@@ -1,3 +1,3 @@
 first line
 second
-third
+third line

当你做了

$ cd client
$ hg update 0

您确保已将SharedLibrary其更新.hgsubstateclient.

然后server,当您访问时,SharedLibrary子存储库不再处于 .revision 1.hgsubstate中提到的修订版本中。换句话说,其中的工作副本是脏的——这将导致一个新文件被提交。serverserverhg commit.hgsubstate

Mercurial会在您进入时保留此修改,这就是为什么您在更新时看到该修改不是最新的。如果您想使子存储库成为当前的,请使用。hg updateserverSharedLibraryhg update -C

此功能背后的想法是您可以测试不同版本的子存储库。在寻找错误时,通常需要将主存储库更新为旧版本,因此对子存储库修订的修改保持在原位很方便。

请注意,您看到的令人困惑的情况不是由您如何重复使用相同的子存储库两次造成的。然而,正如 Lasse 指出的那样,在多个项目中使用单个子存储库的真正方法是将它放在您的服务器上一次,然后将其克隆到您的本地克隆中——每个克隆一次。

我已经更详细地描述了这一点,但简要地说,您应该遵循建议并在服务器和客户端上保持相同的结构。使用文件中SharedLibrary = SharedLibrary的路径.hgsub来维护此结构。在服务器端将存储库链接在一起(请参阅我的其他答案),以使单个存储库出现在几个不同的 URL/目录下。

从 subrepos 开始时,请注意紧耦合。如果可以,请尝试为基于 Java 的项目使用适当的依赖管理系统,例如 Maven+Nexus。

于 2012-03-12T17:08:33.003 回答